package com.stone.richeditor.customtext;

import com.stone.richeditor.ResourceTable;
import com.stone.richeditor.data.DataImage;
import com.stone.richeditor.data.EditData;
import ohos.aafwk.ability.*;
import ohos.agp.components.*;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.Size;
import ohos.multimodalinput.event.KeyEvent;
import ohos.utils.net.Uri;

import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

/**
 * 这是一个富文本编辑器，给外部提供insertImage接口，添加的图片跟当前光标所在位置有关
 * 
 * @author xmuSistone
 * 
 */
public class RichTextEditor extends ScrollView {
	private static final int EDIT_PADDING = 10; // edittext常规padding是10dp
	private static final int EDIT_FIRST_PADDING_TOP = 10; // 第一个EditText的paddingTop值

	private int viewTagIndex = 1; // 新生的view都会打一个tag，对每个view来说，这个tag是唯一的。
	private DirectionalLayout allLayout; // 这个是所有子view的容器，scrollView内部的唯一一个ViewGroup

	private LayoutScatter inflater;

	private KeyEventListener keyListener;

	private OnClickListener onClickListener;

	private ClickedListener closeImage;

	private FocusChangedListener focusChangedListener;

	private TextField lastFocusEdit;
//	private EditingText lastFocusEdit;

	private ComponentTransition mTransition;//LayoutTransition

	private int editNormalPadding = 0; //
	private int disappearingImageIndex = 0;

	public RichTextEditor(Context context) {
		this(context,null);
	}

	public RichTextEditor(Context context, AttrSet attrSet) {
		this(context, attrSet,"");
	}

	public RichTextEditor(Context context, AttrSet attrSet, String styleName) {
		super(context, attrSet, styleName);


		inflater = LayoutScatter.getInstance(context);

		//init allLayout
		allLayout = new DirectionalLayout(context);
		allLayout.setOrientation(DirectionalLayout.VERTICAL);
		allLayout.setScrollbarBackgroundColor(Color.WHITE);

		setupLayoutTransitions();
		DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
		addComponent(allLayout,layoutConfig);

		//init键盘退格监听
		keyListener = new KeyEventListener() {
			@Override
			public boolean onKeyEvent(Component component, KeyEvent keyEvent) {
				if(KeyEvent.KEY_DEL == keyEvent.getKeyCode() && keyEvent.isKeyDown()){
					TextField field = (TextField)component;
					onBackspacePress(field);
				}
				return false;
			}
		};

		//图片叉掉处理
		onClickListener = new OnClickListener() {
			@Override
			public void onClick(int i, AbilityForm abilityForm, ViewsStatus viewsStatus) {
				DependentLayout  directionalLayout = (DependentLayout ) abilityForm.getComponent();
				onImageCloseClick(directionalLayout);
			}
		};

		closeImage =  new ClickedListener() {
			@Override
			public void onClick(Component component) {
				DependentLayout  directionalLayout = (DependentLayout )component.getComponentParent();// component.getComponent();
				onImageCloseClick(directionalLayout);
			}
		};
		focusChangedListener = new FocusChangedListener() {
			@Override
			public void onFocusChange(Component component, boolean b) {
				if(b){
					lastFocusEdit = (TextField)component;
				}
			}
		};

		DirectionalLayout.LayoutConfig layoutConfig1 = new DirectionalLayout.LayoutConfig(LayoutConfig.MATCH_PARENT,
				LayoutConfig.MATCH_PARENT);
		editNormalPadding = dip2px(EDIT_PADDING);
		TextField firstEdit = createEditText("input here", dip2px(EDIT_FIRST_PADDING_TOP));
		firstEdit.setTextSize(70);
		allLayout.addComponent(firstEdit, layoutConfig1);
		lastFocusEdit = firstEdit;
	}
	/**
	 * 生成文本输入框
	 */
	private TextField createEditText(String hint, int paddingTop) {
		TextField editText = (TextField) inflater.parse(ResourceTable.Layout_edit_item1,null,false);
		editText.setKeyEventListener(keyListener);
		editText.setTag(viewTagIndex++);
		editText.setPadding(editNormalPadding, paddingTop, editNormalPadding, 0);
		editText.setHint(hint);
		editText.setFocusChangedListener(focusChangedListener);
		return editText;
	}
	/**
	 * dp和pixel转换
	 *
	 * @param dipValue
	 *            dp值
	 * @return 像素值
	 */
	public int dip2px(float dipValue) {
		return (int) (getContext().getResourceManager().getDeviceCapability().screenDensity / 190 *dipValue);
	}

	/**
	 * 处理软键盘backSpace回退事件
	 *
	 * @param editTxt
	 *            光标所在的文本输入框
	 */
	private void onBackspacePress(TextField editTxt) {
//
		int startSelection = editTxt.getPaddingStart();
		int startlength = editTxt.getTextAlignment();
		// 只有在光标已经顶到文本输入框的最前方，在判定是否删除之前的图片，或两个View合并
		if(editTxt.length() == 0){

			int editIndex = allLayout.getChildIndex(editTxt);
			Component preView = allLayout.getComponentAt(editIndex -1); // 如果editIndex-1<0,
			// 则返回的是null
			if (null != preView) {
				if (preView instanceof DependentLayout) {

					// 光标EditText的上一个view对应的是图片
					onImageCloseClick(preView);
				} else if (preView instanceof TextField) {

					// 光标EditText的上一个view对应的还是文本框EditText
					String str1 = editTxt.getText().toString();
					TextField preEdit = (TextField) preView;
					String str2 = preEdit.getText().toString();

					// 合并文本view时，不需要transition动画
					allLayout.setComponentTransition(new ComponentTransition());
					allLayout.removeComponent(editTxt);
					allLayout.setComponentTransition(mTransition);
					//allLayout.setLayoutTransition(mTransitioner); // 恢复transition动画

					// 文本合并
					preEdit.setText(str2 + str1);
					preEdit.requestFocus();
					preEdit.scrollBy(str2.length(),str2.length());
					//preEdit.scrollTo(str2.length(),str2.length());
					//preEdit.(str2.length(), str2.length());
					lastFocusEdit = preEdit;
				}
			}
		}
	}



	/**
	 * 处理图片叉掉的点击事件
	 *
	 * @param view
	 *            整个image对应的relativeLayout view
	 * @type 删除类型 0代表backspace删除 1代表按红叉按钮删除
	 */
	private void onImageCloseClick(Component view) {
			disappearingImageIndex = allLayout.getChildIndex(view);
			allLayout.removeComponent(view);
	}

	private void setupLayoutTransitions() {
		mTransition = new ComponentTransition();
		allLayout.setComponentTransition(mTransition);
		mTransition.setTransitionTypeDuration(0,300);

	}


	/**
	 * 插入图片处理部分
	 */

	/**
	 * 根据绝对路径添加view
	 *
	 * @param imagePath
	 */
	public void insertImage(String imagePath) {
//		PixelMap bmp = getPixelMap(imagePath);//getScaledBitmap(imagePath, getWidth());
		PixelMap bmp = getScaledBitmap(imagePath, getWidth());
		insertImage(bmp, imagePath);
	}

	/**
	 *
	 * @param pixelMap
	 * @param imagePath
	 */

	public void insertImageExtens(PixelMap pixelMap,String imagePath) {
		insertImage(pixelMap, imagePath);
	}

	/**
	 * 插入一张图片
	 */
	private void insertImage(PixelMap bitmap, String imagePath) {
		String lastEditStr = lastFocusEdit.getText().toString();
		//lastFocusEdit.getPaddingStart()
		int cursorIndex = lastFocusEdit.getPaddingStart();//lastFocusEdit.getSelectionStart();
		String editStr1 = null;
		if(lastEditStr.length() != 0) {
		 //editStr1 = lastEditStr.substring(0, cursorIndex).trim();
		 editStr1 = lastEditStr.substring(0, lastEditStr.length()).trim();
		}
		int lastEditIndex = allLayout.getChildIndex(lastFocusEdit);

		if (lastEditStr.length() == 0 || editStr1.length() == 0) {
			//ShowToast.showToast("if editStr1="+editStr1);
			// 如果EditText为空，或者光标已经顶在了editText的最前面，则直接插入图片，并且EditText下移即可
			addImageViewAtIndex(lastEditIndex, bitmap, imagePath);
		} else {
			//ShowToast.showToast("else editStr1="+editStr1);
			// 如果EditText非空且光标不在最顶端，则需要添加新的imageView和EditText
			lastFocusEdit.setText(editStr1);
			//String editStr2 = lastEditStr.substring(cursorIndex).trim();
			String editStr2 = lastEditStr.substring(lastEditStr.length()).trim();
			if (allLayout.getChildCount() - 1 == lastEditIndex
					|| editStr2.length() > 0) {
				addEditTextAtIndex(lastEditIndex + 1, editStr2);

			}
			addImageViewAtIndex(lastEditIndex + 1, bitmap, imagePath);
			lastFocusEdit.requestFocus();
			lastFocusEdit.scrollBy(editStr1.length(), editStr1.length());
		}
		//hideKeyBoard();
	}

	/**
	 * 在特定位置插入EditText
	 *
	 * @param index
	 *            位置
	 * @param editStr
	 *            EditText显示的文字
	 */
	private void addEditTextAtIndex(final int index, String editStr) {
		TextField editText2 = createEditText(" ", 0);
		editText2.setText(editStr);
		editText2.setTextSize(70);
		// 请注意此处，EditText添加、或删除不触动Transition动画
		//allLayout.setLayoutTransition(null);
		//allLayout.setComponentTransition(null);
		allLayout.addComponent(editText2, index);
		allLayout.setComponentTransition(mTransition); // remove之后恢复transition动画
	}

	/**
	 * 隐藏小键盘
	 * OHOS无此接口
	 */
//	public void hideKeyBoard() {InputMethodSetting
//		InputMethodSetting imm = (InputMethodManager) getContext()
//				.getSystemService(Context.INPUT_METHOD_SERVICE);
//		imm.hideSoftInputFromWindow(lastFocusEdit.getWindowToken(), 0);
//	}

	/**
	 * 在特定位置添加ImageView
	 */
	private void addImageViewAtIndex(final int index, PixelMap bmp,
									 String imagePath) {
		final DependentLayout imageLayout = createImageLayout();
		DataImage imageView = (DataImage) imageLayout
				.findComponentById(ResourceTable.Id_edit_imageView);
		imageView.setPixelMaps(bmp);
		imageView.setPixelMap(bmp);
		imageView.setAbsolutePath(imagePath);

		// 调整imageView的高度
		int imageHeight =  getWidth() * bmp.getImageInfo().size.width / bmp.getImageInfo().size.height;
		DependentLayout.LayoutConfig lp = new DependentLayout.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,imageHeight);
		imageView.setLayoutConfig(lp);
		getContext().getUITaskDispatcher().delayDispatch(new Runnable() {
			@Override
			public void run() {
				allLayout.addComponent(imageLayout,index);
			}
		}, 200);
		// onActivityResult无法触发动画，此处post处理
//		allLayout.postLayout(new Runnable() {
//			@Override
//			public void run() {
//				allLayout.addView(imageLayout, index);
//			}
//		}, 200);
	}
	/**
	 * 生成图片View
	 */
	private DependentLayout createImageLayout() {
		DependentLayout layout = (DependentLayout) inflater.parse(
				ResourceTable.Layout_edit_imageView, null,false);
		layout.setTag(viewTagIndex++);
		Component closeView = layout.findComponentById(ResourceTable.Id_image_close);//layout.findViewById(R.id.image_close);
		closeView.setTag(layout.getTag());
		closeView.setClickedListener(closeImage);
		//closeView.setClickedListener((ClickedListener) onClickListener);
		return layout;
	}
	/**
	 * 根据view的宽度，动态缩放bitmap尺寸
	 *
	 * @param imagePath
	 *            view的宽度
	 */
	private PixelMap getPixelMap(String imagePath) {
		ImageSource imageSource =  imageSource = ImageSource.create(imagePath, null);
		return imageSource.createPixelmap(null);
	}

	private PixelMap getScaledBitmap(String filePath, int width) {

		ImageSource.SourceOptions options = new ImageSource.SourceOptions();

		int sampleSize = options.baseDensity > width ? options.baseDensity / width
				+ 1 : 1;
		DataAbilityHelper helper = DataAbilityHelper.creator(getContext());
		try {
			FileDescriptor fd = helper.openFile(Uri.parse(filePath), "r");
			ImageSource source = ImageSource.create(fd, null);
			ImageSource.DecodingOptions options2 = new ImageSource.DecodingOptions();
			options2.sampleSize = sampleSize;
			return source.createThumbnailPixelmap(options2, true);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 对外提供的接口, 生成编辑数据上传
	 */
	public List<EditData> buildEditData() {
		List<EditData> dataList = new ArrayList<EditData>();
		int num = allLayout.getChildCount();
		for (int index = 0; index < num; index++) {
			Component itemView = allLayout.getComponentAt(index);
			EditData itemData = new EditData();
			if (itemView instanceof TextField) {
				TextField item = (TextField) itemView;
				itemData.inputStr = item.getText().toString();
			} else if (itemView instanceof DependentLayout) {
				DataImage item = (DataImage) itemView
						.findComponentById(ResourceTable.Id_edit_imageView);
				itemData.imagePath = item.getAbsolutePath();
				itemData.bitmap = item.getPixelMap();
			}
			dataList.add(itemData);
		}

		return dataList;
	}

}
